package com.apestech.framework.util;

import com.apestech.api.xml.esb.EsbUtil;
import com.apestech.framework.json.JSONObject;
import com.apestech.framework.util.callback.JSONMapKeyInter;

import java.util.ArrayList;

/**
 * @author hup
 * @create 2019-11-28-9:38
 */
public class DataMappingUtil extends StringUtil{

    private class Field {
        private String value;
        private boolean isVar;
        private boolean isArray;

        public String getValue() {
            return value;
        }

        public void setValue(String value) {
            this.value = value;
        }

        public boolean isVar() {
            return isVar;
        }

        public void setVar(boolean var) {
            isVar = var;
        }

        public boolean isArray() {
            return isArray;
        }

        public void setArray(boolean array) {
            isArray = array;
        }
    }

    protected class ID_VAR {
        private String id;
        private String var;

        public ID_VAR(String value){
            int pos=value.indexOf("#");
            if(pos>0){
                id=value.substring(0, pos);
                var=value.substring(pos+2, value.length()-1);
            } else id=value;
        }

        public String getId() {
            return id;
        }

        public String getVar() {
            return var;
        }
    }

    protected JSONObject getFormJson(JSONObject param, boolean bform, String theme, JSONMapKeyInter jsonMapKeyInter) throws Exception {
        if(param==null) return null;
        String type=param.getString("type");
        JSONObject typeJson;
        if(bform) typeJson= EsbUtil.getFormType(type, theme);
        else typeJson= EsbUtil.getGridType(type, theme);
        return getOutJson(typeJson, param, theme, jsonMapKeyInter);
    }

    protected JSONObject getOutJson(JSONObject input, JSONObject param, String theme, JSONMapKeyInter jsonMapKeyInter) throws Exception {
        JSONObject out=new JSONObject();
        ArrayList<String> klist=input.getKeylist();
        int len=klist.size();
        for(int i=0; i<len; i++){
            String k=klist.get(i);
            Object obj=input.get(k);
            if(obj instanceof JSONObject){
                out.put(k, getOut(k, (JSONObject) obj, param, theme, jsonMapKeyInter));
            } else {
                setSingleValue(k, (String) obj, out, param, theme, jsonMapKeyInter);
            }
            if(out.get(k)==null) out.remove(k);
        }
        return out;
    }

    private JSONObject getOut(String key, JSONObject input, JSONObject param, String theme, JSONMapKeyInter jsonMapKeyInter) throws Exception{
        JSONObject o=new JSONObject();
        ArrayList<String> klist=input.getKeylist();
        int len=klist.size();
        for(int i=0; i<len; i++) {
            String k = klist.get(i);
            Object obj = input.get(k);
            if (obj instanceof JSONObject) {
                o.put(k, getOut(key, (JSONObject) obj, param, theme, jsonMapKeyInter));
            } else {
                setSingleValue(k, (String) obj, o, param, theme, jsonMapKeyInter);
            }
            if(o.get(k)==null) o.remove(k);
        }
        return o;
    }

    private void setSingleValue(String k, String vkey, JSONObject out, JSONObject param, String theme, JSONMapKeyInter jsonMapKeyInter) throws Exception {
        Field v=getVar(vkey);
        if(v.isVar()){
            out.put(k, param.get(v.getValue()));
        } else out.put(k, vkey);
        if(out.get(k)==null){
            String fvar = EsbUtil.getFormField(k, theme);
            if (fvar != null) {
                out.put(k, fvar);
            }
        }
        Object obj=jsonMapKeyInter.getValue(k, v.getValue());
        if(obj!=null) out.put(k, obj);
    }

    private Field getVar(String fvar){
        fvar=fvar.trim();
        int pos=fvar.indexOf("#{");
        Field f=new Field();
        if(pos==0){
            f.setVar(true);
            pos=fvar.indexOf("*");
            int len=fvar.length();
            if(pos==len-1){
                f.setArray(true);
                f.setValue(fvar.substring(2, len-2));
            }
            else {
                f.setArray(false);
                f.setValue(fvar.substring(2, len-1));
            }
        } else {
            pos=fvar.indexOf("*");
            int len=fvar.length();
            if(pos==len-1){
                f.setValue(fvar.substring(0, len-1));
                f.setArray(true);
            } else {
                f.setValue(fvar);
                f.setArray(false);
            }
            f.setVar(false);
        }
        return f;
    }

    public ID_VAR getIdVar(String value){
        ID_VAR idv=new ID_VAR(value);
        return idv;
    }
}
